package com.seecode.UnitClass;

import android.app.Activity;

import com.seecode.LightWebView;
import com.seecode.Logs;
import com.seecode.Utils.Utils;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by Administrator on 2017/10/19.
 */

public class CodeView {


    String charCode="utf-8";
    String header;
    String tail;
    boolean isOneBlock=true;
    int currentBlock=0;
    String[] rawContent;

    List<FuncName> funcList = new ArrayList<>();
    int mLine=0;
    List<LightWebView> webList=new ArrayList<>();
    int mblock=0; //if file too big  sepret to see
    int fileSize; //Kb
    Activity activity;


    public CodeView(Activity activity) {
        this.activity=activity;

    }

    public class FuncName{
        public String name;
        public int atLine=1;
        public int block=0;

        public FuncName(String name, int atLine) {
            this.name = name;
            this.atLine = atLine;

        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public int getAtLine() {
            return atLine;
        }

        public void setAtLine(int atLine) {
            this.atLine = atLine;
        }

        public int getBlock() {
            return block;
        }

        public void setBlock(int block) {
            this.block = block;
        }
    }
    public void clear(){

        this.isOneBlock=true;
        if(currentBlock != 0) {
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    webList.get(currentBlock).setLook(false);
                    webList.get(0).setLook(true);
                }
            });

        }
        this.currentBlock=0;
        if(funcList.size()>0){
            funcList.clear();
        }


        this.mLine=0;
        this.mblock=0; //if file too big  sepret to see

    }
    public void showHtml(String content){

        this.rawContent = content.split("\n");
        this.fileSize = content.length()/1000;
        Logs.i("fileSize:"+fileSize);

        new Thread(new Runnable() {
            @Override
            public void run() {
                handleUrlContent();
            }
        }).start();

    }

    public  String[] getFunList(){
        int n = funcList.size();

        String[] funList = new String[n];
        for(int i=0;i < n ;i++){

            funList[i] = funcList.get(i).getName();
        }

        return funList;
    }
    private void handleUrlContent(){

        clear();
        int n = rawContent.length;
        Logs.i("rawCon len is "+n);
        mLine = n;


        for(int i=0;i<n;i++){
            int ret =isFunName(rawContent[i]);
            if(ret == 1){
              String out = addSign(rawContent[i],i);//recod funName line and name in the file
                //handle xx(int a,  to ##xx## xx(int a,give js to handle
                Logs.i("new string line func is "+out);
                rawContent[i]=out;
            }else if(ret == -1){

                rawContent[i] = rawContent[i].replace("<","&lt").replace(">","&gt");
                Logs.i("I hate this < and >");
            }
        }
        loadHeader();
        loadTail();
        splitConntent();


    }
    public void addLightWebView(LightWebView lightWebView){

        webList.add(lightWebView);
    }
    public void  splitConntent(){
        int level = fileSize;

        mblock=0;


           if( level < 120) {

               mblock = 1;
           }else if(level < 200){
                mblock=2;

           }else if(level < 30){
                mblock=3;

           }else if(level < 400){
                mblock=4;

           }else if(level < 500){
                mblock=5;

           }else if(level < 600){
                mblock=6;

           }else if(level < 700){
                mblock=7;

           }else if(level < 800){
                mblock=8;

           }else if(level < 900){
                mblock=9;

           }else if(level < 1000){

            mblock = 10;
           }else{

            Logs.i("too big how to do?????");
            mblock = 10;
            }
        if(funcList.size()<1){

            mblock=1;
        }
        Logs.i("it seperate block num is "+mblock);

        if(mblock==1){

            isOneBlock=true;
            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Utils.showToast("拼命加载中稍等哦o_o_o_o_o");

                    webList.get(0).show(rawContent,header,tail).setLook(true);



                    Logs.i("ok brother you now alone working");
                }
            });

            Logs.i("ou this file only one block");
        }else{
            isOneBlock=false;
            int n=mblock;
            Logs.i("now will "+ mblock+" friend workling together");
            int aver = mLine/mblock;
            int first = 1;
            int[] leve = new int[mblock+1];
            leve[0]=1;
            for(int i=0;i<n;i++){

                final int num = isInCode(aver*(i+1));
                final LightWebView web = webList.get(i);
                final String header0 = header;
                final String tail0 =tail;
                final int  first0 = first;
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {

                        web.show(rawContent,first0,num,header0,tail0);
                        Logs.i("we still loading ......");

                    }
                });

                //both all webview start load ---____----
                Logs.i("the "+i+" block start "+ first+" end:"+num);
                first=num+1;
                leve[i+1]=num;//load block num border

            }

            Logs.i("ok first block could see");
            handleFunBlock(leve);//one block not need split
        }


    }
    public int getBlocks(){

        return mblock;
    }
    public int getCurrentBlock(){

        return currentBlock;
    }


    private void handleFunBlock(int[] level){

        if(funcList.size()<=0){
            Logs.i("---__---- no funcname");
            return;
        }

        int n = funcList.size();
        Logs.i("funcName is "+n+" count");
        int count = level.length;
        for(int i=0;i < count;i++){

            Logs.i("leve "+i+" is "+level[i]);
        }

        for(int i=0;i<n;i++){

            FuncName a = funcList.get(i);
            boolean find =false;
            //Logs.i("name:"+a.getName()+" line is"+a.getAtLine());
            for(int j=0; j <count-1;j++){

                if((a.getAtLine()>= level[j]) && (a.getAtLine() < level[j+1])){

                    a.setBlock(j);
                    Logs.i("ok I find the "+"level is:"+(j+1));
                    find =true;
                    break;
                }
            }
            if(!find){
               // Logs.i("why "+a.getName()+" my Line is "+a.getAtLine()+"why no find my block");
            }
        }
        //webList.get(0).setLook(true);
        Utils.showToast("All func is handle ok----_0!--");


            activity.runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    Utils.showToast("拼命加载中稍等哦o_o_o_o_o");

                    webList.get(currentBlock).setLook(false);
                    webList.get(0).setLook(true);
                }
            });
       currentBlock=0;
        Logs.i("we handle function collection over----__------");
    }
    public void loadHeader(){
        if(header != null){
            return ;
        }
        header =Utils.readAssetsContent("/assets/head1.txt")+ Utils.readAssetsContent("/assets/js/prism.css")+Utils.readAssetsContent("/assets/head2.txt");

    }
    public void loadTail(){
        if(tail != null){
            return ;
        }
        tail =Utils.readAssetsContent("/assets/tail1.txt")+ Utils.readAssetsContent("/assets/js/prism.js")+Utils.readAssetsContent("/assets/tail2.txt");

    }



    public void showCode(String funName){
        Logs.i("showCode funName is:"+funName);

        if(isOneBlock){

            webList.get(0).moveToFunName(funName);
            Logs.i("what one working ");


        }else {
            Logs.i("haha many boy working");
            int n = funcList.size();
            int newBlock=0;
            int changed=0;
            for(int i=0;i < n; i++){
                FuncName a = funcList.get(i);
                if(a.getName().equals(funName)){
                    newBlock = a.getBlock();
                    Logs.i("this func is belong to "+newBlock+" block");
                    changed=1;
                    break;
                }
            }
            if(changed == 0){

                Logs.i("what no find funName block come on you should addgas");
            }
            if(newBlock != currentBlock){
                Logs.i("last block is:"+currentBlock);
                Logs.i("new block is "+newBlock);
                webList.get(currentBlock).setLook(false);
                currentBlock = newBlock;
            }else{

                Logs.i("what no change for webView ");
            }

            for(int i=0;i<10;i++){

                if(i == currentBlock){

                    webList.get(i).setLook(true);
                    webList.get(i).moveToFunName(funName);
                    continue;
                }
                webList.get(i).setLook(false);
            }

        }




    }

    public int isInCode(int avLine){


        Logs.i("avLine"+avLine);
        int size = funcList.size();
        int i=0;
        int firstIndex =funcList.get(0).getAtLine();
        int beforeIndex=0;
        boolean isFind=false;
        int pos = avLine;
        while(i < size){

            Logs.i("the firstIndex:"+firstIndex+" the avLine"+avLine);
            if(firstIndex < avLine){
                i++;
                if(i == size){

                    break;
                }
                firstIndex = funcList.get(i).getAtLine();
                continue;
            }else{

                isFind=true;
                firstIndex=funcList.get(i).getAtLine();
                break;
            }

        }
        if(isFind){
            if(i==0){//if is first func line big than line

                pos = funcList.get(0).getAtLine()-1;
            }else {
                beforeIndex = funcList.get(i-1).getAtLine();
                pos = Math.abs(firstIndex - avLine) > Math.abs(avLine - beforeIndex) ? (beforeIndex - 1) : (firstIndex - 1);

            }

        }else{ // if the last func small than line
            if(i == size){

                pos = funcList.get(i-1).getAtLine()-1;
            }
        }
        Logs.i("finnaly avLineis:"+pos);
        return pos;

    }
    public String  addSign(String str,int line){

        String[] ret = str.split(" ");
        int n =ret.length;
        int pos=0;
        for(int i=0;i<n;i++){


            if((pos=ret[i].indexOf("("))>=0){

                String fName=ret[i].substring(0,pos);
                //Logs.i("funName is :"+fName+" line is"+line);
                funcList.add(new FuncName(fName,line));

                ret[i]= "##"+fName+"## "+ret[i];//##name## name(xx
                break;
            }
        }
        StringBuffer stringBuffer = new StringBuffer();
        for(int i=0;i<n;i++){

            stringBuffer.append(ret[i]+" ");
        }

        return stringBuffer.toString();

    }


    public void adjustFont(){

        webList.get(currentBlock).adjustFont();
    }
    public int  isFunName(String content){
            //排除正常语句和注释
            if(content.indexOf("*") >= 0){


                int pos =content.indexOf("*");
                if(content.indexOf("<a") >= 0 || content.indexOf("a>") >= 0){

                    return -1;
                }
                    //repaire bug  <code>  this in the anno disturb the higiht
                if((content.indexOf("<") >= 0) && (content.indexOf(">") >= 0 )){
                   // so low to see both *  and >  and <  example  a*b > x && a*b <x
                    return -1;//fuck this <p> will disturb linenum to see;
                }

                return 0;
            }

            if(content.indexOf(";") >= 0 || content.indexOf("=") >= 0 || content.indexOf("+") >= 0 || content.indexOf("//") >= 0  || content.indexOf(" new ") >= 0){
                //logs("1111"+content);
                return 0;
            }
            //排除单个}
            if(content.length() < 5){// {  this  condiction}
                // logs("222"+content);
                return 0;
            }
            //正向排除
            if(  content.indexOf("(") < 0 || content.indexOf(")") < 0 || content.indexOf("{") <0){

                //logs("333333333"+content);
                return 0;
            }
            //paichu if(){}  when(){ for({类似干扰
            if(!(content.indexOf("public")>=0 ||content.indexOf("private")>=0 || content.indexOf("protected")>=0)){
                //logs("444"+content);
                return 0;
            }
            return 1;
    }


}
